﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Com.PhilChuang.Mobile.Apps.LocationSender.Model;
using Com.PhilChuang.Mobile.Apps.LocationSender.Model.Data;
using Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views;
using Com.PhilChuang.Pmvp.Ui.Presenters;
using Com.PhilChuang.Utils;

namespace Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Presenters
{
	public abstract class AbstractLocationSenderAppPresenter<TView> : AbstractAppPresenter<TView, LocationSenderApp>
		where TView : class, ILocationSenderView
	{
		protected readonly LocationSenderApp m_App;
		protected GeoCoordinate m_CurrentCoords;
		protected string m_AppStatus;

		protected AbstractLocationSenderAppPresenter (TView view) : this (AppServiceLocator.Instance.GetImpl<LocationSenderApp> (), view)
		{
		}

		protected AbstractLocationSenderAppPresenter (LocationSenderApp app, TView view) : base (app, view)
		{
			app.ThrowIfNull ("app");
			m_App = app;
		}

		/// <summary>
		/// Fires when the App is registered with the Presenter during Presenter instantiation.
		/// Call base impl as first step.
		/// </summary>
		protected override void OnAppRegistered ()
		{
			base.OnAppRegistered ();
			m_CurrentCoords = App.CurrentPosition;
			m_AppStatus = App.Status;
		}

		/// <summary>
		/// Subscribe to App events after the App is registered during Presenter instantiation.
		/// Call base impl as the first step.
		/// </summary>
		protected override void SubscribeToAppEvents ()
		{
			base.SubscribeToAppEvents ();
			
			App.StatusChanged += OnStatusChanged;
			App.GeoCoordinateUpdated += OnGpsCoordsUpdated;
			App.OnLocationServiceUnavailable += OnOnLocationServiceUnavailable;
		}

		/// <summary>
		/// Unsubscribes to View events after the View has Closed.
		/// Call base impl as the first step.
		/// </summary>
		protected override void UnsubscribeToAppEvents ()
		{
			base.UnsubscribeToAppEvents ();

			App.StatusChanged -= OnStatusChanged;
			App.GeoCoordinateUpdated -= OnGpsCoordsUpdated;
			App.OnLocationServiceUnavailable -= OnOnLocationServiceUnavailable;
		}

		/// <summary>
		/// Updates the View with Presenter data.
		/// Call base impl as the last step.
		/// </summary>
		protected override void UpdateToView ()
		{
			View.AppStatus = m_AppStatus;
			View.CurrentPosition = m_CurrentCoords;

			base.UpdateToView ();
		}

		/// <summary>
		/// Fires every time the View is Shown.
		/// Base impl refreshes view data if that hasn't occurred yet.
		/// Call base impl as the last step.
		/// </summary>
		protected override void OnViewShown ()
		{
			if (LocationSenderApp.HasExceptionLog)
			{
				ExecuteAsync (() => {
				              	WaitForViewShown ();
				              	new ReportBugPresenter ().Show ();
				              });
			}
			base.OnViewShown ();
		}

		private void OnStatusChanged (String status)
		{
			m_AppStatus = status;
			ExecuteAsync (() => {
			              	WaitForViewShown ();
			              	View.AppStatus = m_AppStatus;
			              });
		}

		private void OnGpsCoordsUpdated (GeoCoordinate gps)
		{
			m_CurrentCoords = gps;
			ExecuteAsync (() => {
			              	WaitForViewShown ();
							View.CurrentPosition = m_CurrentCoords;
			              });
		}

		private void OnOnLocationServiceUnavailable ()
		{
			View.DisplayErrorMessage ("Sorry, it looks like your Location service is disabled! Go to your device's settings menu, select location, and turn it on.", "Location services unavailable");
		}

		// going to be a free app
		//protected void HandleTrialModeException (TrialModeException ex)
		//{
		//    if (View.DisplayYesNoChoice ("{0}\r\nWould you like go to the marketplace and buy this app?".FormatWith (ex.Message), "Trial Limitation"))
		//    {
		//        App.LaunchMarketplaceAppDetails ();
		//    }
		//    else
		//    {
		//        View.EnableAllControls (true);
		//    }
		//}
	}
}